home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 18 / AMIGAplus Sonderheft 18 (1999)(ICP)(DE)[!].iso / PD / Anwendungen / FS1541-13 / main.c < prev    next >
C/C++ Source or Header  |  1999-01-03  |  11KB  |  325 lines

  1.  
  2. /*
  3.  * FS1541 - the handler entry point
  4.  *
  5.  * Copyright (C) 1996 - 1998 Michael Krause
  6.  *
  7.  * This program is free software; you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License as published by
  9.  * the Free Software Foundation; either version 2 of the License, or
  10.  * (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  20.  */
  21.  
  22. #include <string.h>
  23.  
  24. #include <exec/types.h>
  25. #include <exec/execbase.h>
  26. #include <dos/dos.h>
  27. #include <dos/dosextens.h>
  28. #include <dos/dostags.h>
  29. #include <dos/filehandler.h>
  30. #include <utility/utility.h>
  31. #include <devices/timer.h>
  32.  
  33. #include <proto/exec.h>
  34. #include <proto/dos.h>
  35.  
  36. #include "main.h"
  37. #include "packet.h"
  38. #include "disk.h"
  39. #include "volume.h"
  40. #include "support.h"
  41.  
  42. char verstring[] = "$VER: 1541-handler 1.3 (1.1.99)";
  43.  
  44. struct ExecBase *SysBase;
  45. struct DosLibrary *DOSBase;
  46. struct UtilityBase *UtilityBase, *__UtilityBase;
  47.  
  48. struct Task *ourtask;
  49. struct MsgPort *ourport;
  50.  
  51. struct FileSysStartupMsg *fssm;
  52.  
  53. static UBYTE diskinfo_image[] = {
  54. 0xE3,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x3D,0x00,0x37,0x00,0x2A,
  55. 0x00,0x04,0x00,0x01,0x00,0x01,0x07,0x57,0x3F,0xD0,0x00,0x00,0x00,0x00,0x00,0x00,
  56. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
  57. 0x01,0x10,0x07,0x57,0x66,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
  58. 0x00,0x3D,0x07,0x5B,0xCB,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,
  59. 0x00,0x30,0x01,0x64,0x00,0xB7,0xFF,0xFF,0x00,0x00,0x00,0x00,0x02,0x00,0x12,0x7F,
  60. 0x07,0x5B,0xCB,0x66,0x00,0x00,0x00,0x00,0x07,0x57,0x66,0xBC,0x00,0x00,0x00,0x00,
  61. 0x00,0x00,0x00,0x00,0x00,0x5A,0x00,0x45,0xFF,0xFF,0xFF,0xFF,0x00,0x01,0x00,0x00,
  62. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x00,0x29,0x00,0x02,
  63. 0x00,0x03,0x3A,0xD0,0x03,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  64. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xC0,0x00,0x00,0x00,
  65. 0x1E,0x00,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x1E,0x00,0xFF,0xFF,0xC0,0xF8,0x0B,0xAA,
  66. 0x1E,0x00,0xFF,0xFF,0xC1,0xFB,0xCA,0x2A,0x1E,0x00,0xFF,0xFF,0xC1,0x83,0x8A,0x2A,
  67. 0x1E,0x00,0xFF,0xFF,0xC1,0x80,0x0B,0x1A,0x1E,0x00,0xFF,0xFF,0xC1,0x83,0x88,0x8A,
  68. 0x1E,0x00,0x3F,0xFF,0xC1,0xFB,0xCA,0x8A,0x18,0x00,0x3F,0xFF,0xC0,0xF8,0x0B,0x8A,
  69. 0x18,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x00,0x18,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  70. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  71. 0xFE,0x00,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,
  72. 0xFE,0x00,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,
  73. 0xFE,0x00,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,0xFE,0x00,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,
  74. 0xFE,0x00,0xFF,0xFF,0xFC,0x00,0x7F,0xFF,0xFE,0x00,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,
  75. 0xFE,0x00,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,
  76. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  77. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  78. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  79. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  80. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  81. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  82. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  83. 0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  84. 0xFE,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
  85. 0x00,0x00,0x80,0x00,0x3F,0xFF,0xFF,0xFF,0xE0,0x00,0x80,0x00,0x3F,0xFF,0xFF,0xFF,
  86. 0xE0,0x00,0x80,0x00,0x3F,0x07,0xF4,0x55,0xE0,0x00,0x80,0x00,0x3E,0x04,0x35,0xD5,
  87. 0xE0,0x00,0x80,0x00,0x3E,0x7C,0x75,0xD5,0xE0,0x00,0x80,0x00,0x3E,0x7F,0xF4,0xE5,
  88. 0xE0,0x00,0x80,0x00,0x3E,0x7C,0x77,0x75,0xE0,0x00,0x20,0x00,0x3E,0x04,0x35,0x75,
  89. 0xE0,0x00,0x20,0x00,0x3F,0x07,0xF4,0x75,0xE0,0x00,0x20,0x00,0x3F,0xFF,0xFF,0xFF,
  90. 0xE0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
  91. 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,
  92. 0x00,0x00,0x80,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,
  93. 0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,
  94. 0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
  95. 0x00,0x00,0x80,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x04,0x20,0x00,
  96. 0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x20,0x00,
  97. 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
  98. 0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
  99. 0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
  100. 0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
  101. 0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
  102. 0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
  103. 0x00,0x00,0x80,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
  104. 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x53,0x59,
  105. 0x53,0x3A,0x53,0x79,0x73,0x74,0x65,0x6D,0x2F,0x44,0x69,0x73,0x6B,0x43,0x6F,0x70,
  106. 0x79,0x00,0x00,0x00,0x00,0x02,0x00,0x02
  107. };  
  108.  
  109. UBYTE *diskiconimg = diskinfo_image;
  110. int diskiconlength = sizeof(diskinfo_image);
  111.  
  112. static ULONG argarray[6] = { 0, 0, 0, 0, 0, 0 };
  113.  
  114. /*-------------------------------------------------------------------------*/
  115.  
  116. static BOOL MakeFSSM(BSTR startup)
  117. {
  118.     UBYTE str[258];
  119.     STRPTR src = BADDR(startup);
  120.     struct RDArgs *rdargs;
  121.  
  122.     if(src)
  123.     {
  124.         int i,len = src[0];
  125.  
  126.         /* Convert startup string */
  127.         CopyMem(&src[1], str, len);
  128.         str[len] = '\n';
  129.         str[len+1] = '\0';
  130.  
  131.         for(i=0;i<len;i++)
  132.             if(str[i] == '"') str[i] = ' ';
  133.  
  134.         if((rdargs = (struct RDArgs*)AllocDosObject(DOS_RDARGS, NULL)))
  135.         {
  136.             static char template[]=
  137.                 "D=DEVICE/A,"
  138.                 "U=UNIT/N/A,"
  139.                 "F=FLAGS/N,"
  140.                 "NS=NOAUTOSCAN/S,"
  141.                 "I=INTERLEAVE/N,"
  142.                 "ICON/K";
  143.  
  144.             rdargs->RDA_Flags |= RDAF_NOPROMPT;
  145.             rdargs->RDA_Source.CS_Buffer = str;
  146.             rdargs->RDA_Source.CS_Length = strlen(str);
  147.             rdargs->RDA_Source.CS_CurChr = 0;
  148.  
  149.             if(ReadArgs(template, argarray, rdargs))
  150.             {
  151.                 if((fssm = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC)))
  152.                 {
  153.                     struct DosEnvec *env;
  154.                     STRPTR name;
  155.  
  156.                     if((env = AllocVec(sizeof(struct DosEnvec), MEMF_PUBLIC|MEMF_CLEAR)))
  157.                     {
  158.                         if((name = AllocVec(strlen((STRPTR)argarray[0])+2, MEMF_PUBLIC)))
  159.                         {
  160.                             strcpy(name+1, (STRPTR)argarray[0]);
  161.                             name[0] = strlen(name+1);
  162.  
  163.                             fssm->fssm_Unit = *(ULONG*)argarray[1];
  164.                             fssm->fssm_Device = (BPTR)MKBADDR(name);
  165.                             fssm->fssm_Flags = argarray[2] ? *(ULONG*)argarray[2] : 16;
  166.                             fssm->fssm_Environ = (BPTR)MKBADDR(env);
  167.  
  168.                             /* These might be strange settings, but we must announce
  169.                                the device as one single track with 683 sectors, other-
  170.                                wise there would be some trouble with formatting etc. */
  171.                             env->de_TableSize = 19;
  172.                             env->de_SizeBlock = 256/4;
  173.                             env->de_Surfaces = 1;
  174.                             env->de_SectorPerBlock = 1;
  175.                             env->de_BlocksPerTrack = 683;
  176.                             env->de_LowCyl = 0;
  177.                             env->de_HighCyl = 0;
  178.                             env->de_DosType = ID_DOS_DISK;
  179.                             env->de_MaxTransfer = 256*683;
  180.                             env->de_Mask = 0x7ffffffe;
  181.                             env->de_NumBuffers = 683;
  182.                             env->de_Reserved = 1;
  183.  
  184.                             if(argarray[3])
  185.                                 autoscan = FALSE;
  186.  
  187.                             if(argarray[4])
  188.                             {
  189.                                 LONG i = *(ULONG*)argarray[4];
  190.                                 if(i>0)
  191.                                     interleave = i;
  192.                             }
  193.  
  194.                             return(TRUE);
  195.                         }
  196.  
  197.                         FreeVec(env);
  198.                     }
  199.                     FreeVec(fssm);
  200.                 }
  201.                 FreeArgs(rdargs);
  202.             }
  203.             FreeDosObject(DOS_RDARGS, rdargs);
  204.         }
  205.     }
  206.  
  207.     return(FALSE);
  208. }
  209.  
  210. static void LoadDiskIcon() {
  211.     if(argarray[5]) {
  212.         BPTR fh;
  213.  
  214.         if((fh = Open((STRPTR)argarray[5], MODE_OLDFILE))) {
  215.             ULONG len;
  216.             APTR data;
  217.  
  218.             Seek(fh, 0, OFFSET_END);
  219.             len = Seek(fh, 0, OFFSET_BEGINNING);
  220.  
  221.             if((data = AllocVec(len, MEMF_ANY))) {
  222.                 if(Read(fh, data, len) != len) {
  223.                     FreeVec(data);
  224.                     data = NULL;
  225.                 }
  226.             }
  227.  
  228.             Close(fh);
  229.  
  230.             if(data) {
  231.                 diskiconimg = data;
  232.                 diskiconlength = len;
  233.             }
  234.         }        
  235.     }
  236. }
  237.  
  238. void entry(void)
  239. {
  240.     struct DosPacket *startuppacket;
  241.     struct DosList *devnode;
  242.     LONG error = ERROR_NO_FREE_STORE;
  243.  
  244.     SysBase = *(volatile APTR*)4;
  245.  
  246.     ourtask = FindTask(NULL);
  247.  
  248.     ourport = &((struct Process *)ourtask)->pr_MsgPort;
  249.     WaitPort(ourport);
  250.     startuppacket = GetPacket(ourport);
  251.  
  252.     devnode = (struct DosList*)BADDR(startuppacket->dp_Arg3);
  253.  
  254.     if((ourport = CreateMsgPort())) {
  255.         if((DOSBase = (struct DosLibrary*)OpenLibrary(DOSNAME, 37)))
  256.         {
  257.             if((UtilityBase = (struct UtilityBase*)OpenLibrary("utility.library",37)))
  258.             {
  259.                 __UtilityBase = UtilityBase;
  260.  
  261.                 /* I'm almost sure that using the MountList `Control' field
  262.                    instead of `Startup' is better; well... next time ;-) */
  263.                 if(MakeFSSM(startuppacket->dp_Arg2))
  264.                 {
  265.                     devnode->dol_misc.dol_handler.dol_Startup = (BPTR)MKBADDR(fssm);
  266.  
  267.                     if(!(error = InitDiskSS(&((STRPTR)BADDR(fssm->fssm_Device))[1],fssm->fssm_Unit,fssm->fssm_Flags)))
  268.                     {
  269.                         if(!(error = InitVolumeSS()))
  270.                         {
  271.                             ULONG pktsig = 1<<(ourport->mp_SigBit);
  272.                             ULONG diskchgsig = 1<<diskchgintbit;
  273.                             ULONG udssig = 1<<(UDStimer->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
  274.                             ULONG mask = pktsig|diskchgsig|udssig;
  275.         
  276.                             error = 0;
  277.                             devnode->dol_Task = ourport;
  278.                             startuppacket->dp_Arg4 = (LONG)ourport;
  279.                             ReturnPacket(startuppacket, DOSTRUE, 0);
  280.             
  281.                             LoadDiskIcon();
  282.  
  283.                             DoDiskInsert();
  284.                 
  285.                             for(;;)
  286.                             {
  287.                                 ULONG sigs;
  288.                         
  289.                                 while(!( SetSignal(0,0)&mask || LoadDisk() ));
  290.             
  291.                                 sigs = Wait(mask);
  292.                         
  293.                                 if(sigs & pktsig)
  294.                                     DoPackets();
  295.                                 if(sigs & udssig)
  296.                                     UpdateDiskStructure();
  297.                                 if(sigs & diskchgsig)
  298.                                 {
  299.                                     if(!inhibited)
  300.                                     {
  301.                                         /* We do the remove for security reasons */
  302.                                         DoDiskRemove();
  303.                                         DoDiskInsert();
  304.                                     }
  305.                                 }
  306.                             }
  307.                 
  308.                             QuitVolumeSS();
  309.                         }
  310.                         QuitDiskSS();
  311.                     }
  312.                 } else error = ERROR_REQUIRED_ARG_MISSING;
  313.                 CloseLibrary((struct Library*)UtilityBase);
  314.             }
  315.             CloseLibrary((struct Library*)DOSBase);
  316.         }
  317.         DeleteMsgPort(ourport);
  318.     }
  319.  
  320.     ourport = &((struct Process *)ourtask)->pr_MsgPort;
  321.  
  322.     if(error)
  323.         ReturnPacket(startuppacket, DOSFALSE, error);
  324. }
  325.